package com.jiang.demo.config.thread;

import com.jiang.demo.common.constans.Constant;
import org.slf4j.MDC;
import org.springframework.core.task.TaskDecorator;

import java.util.Map;
import java.util.UUID;

/**
 * ---------------------------------------------------------------------------------------------------------------
 * - 2024-06-01 15:24 - jiangshaoneng -
 * ---------------------------------------------------------------------------------------------------------------
 * -      ██╗██╗ █████╗ ███╗   ██╗ ██████╗ ███████╗██╗  ██╗ █████╗  ██████╗ ███╗   ██╗███████╗███╗   ██╗ ██████╗
 * -      ██║██║██╔══██╗████╗  ██║██╔════╝ ██╔════╝██║  ██║██╔══██╗██╔═══██╗████╗  ██║██╔════╝████╗  ██║██╔════╝
 * -      ██║██║███████║██╔██╗ ██║██║  ███╗███████╗███████║███████║██║   ██║██╔██╗ ██║█████╗  ██╔██╗ ██║██║  ███╗
 * - ██   ██║██║██╔══██║██║╚██╗██║██║   ██║╚════██║██╔══██║██╔══██║██║   ██║██║╚██╗██║██╔══╝  ██║╚██╗██║██║   ██║
 * - ╚█████╔╝██║██║  ██║██║ ╚████║╚██████╔╝███████║██║  ██║██║  ██║╚██████╔╝██║ ╚████║███████╗██║ ╚████║╚██████╔╝
 * -  ╚════╝ ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝ ╚═════╝ ╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚══════╝╚═╝  ╚═══╝ ╚═════╝
 * ---------------------------------------------------------------------------------------------------------------
 * 处理 使用异步线程执行出现的异常
 * ---------------------------------------------------------------------------------------------------------------
 */
public class CustomTaskDecorator implements TaskDecorator {

    @Override
    public Runnable decorate(Runnable runnable) {
        Map<String, String> contextMap = MDC.getCopyOfContextMap();
        return () -> {
            try {
                if (contextMap != null) {
                    String childMDCId = UUID.randomUUID().toString().replace("-", "").substring(0,8);
                    String UNIQUE_ID_NAME = contextMap.get(Constant.TRACE_ID) + "-" + childMDCId;
                    contextMap.put(Constant.TRACE_ID, UNIQUE_ID_NAME);
                    MDC.setContextMap(contextMap);
                }
                runnable.run();
            } finally {
                MDC.clear();
            }
        };
    }
}
